#ifndef MESSAGE_H
#define MESSAGE_H
// includes
#include "common.h"

// defines
typedef int msg_type;
#define MESSAGE_SIZE 1

#define DESTROY_PACKET_LIST(X) { \
    destroyPacketList(X); \
    X = NULL; \
    }
#define MESSAGE_COPY(DST, SRC) { \
    memcpy((DST)->data, (SRC)->data, MESSAGE_SIZE * sizeof(msg_type)); \
    }

// typedefs
typedef struct message
{
    msg_type data[MESSAGE_SIZE];
}Message;

// structure representing a single message/packet
typedef struct packet
{
    int from;
    int to;

    Message payload;

    struct packet *next;
}Packet;

// structure that holds a list of messages
typedef struct packetList
{
    int packetCount;
    Packet *head;
}PacketList;

// declarations
// create a new message object
Packet* getPacket();

// create a new message list holder
PacketList* createPacketList();

// return a message object after use for reuse
void returnPacket(Packet *packet);

// destroy/unallocate a message list holder and return
// messages in the list holder
void destroyPacketList(PacketList *packetList);

// initialize messaging module
void msgInitialize();

// uninitialize messaging module
void msgTerminate();

// put a message in a message list
void pushPacket(PacketList *list, Packet *packet);

// take out a message from message list
Packet* popPacket(PacketList *list);

// takes out a message from given inbox
bool recvMessage(PacketList *inbox, Message *msg, int *from);

// puts a message in given outbox
bool sendMessage(PacketList *outbox, Message *msg, int from, int to);
#endif /* MESSAGE_H */